<template>
  <div class="file-uploader">
    <el-upload
      v-model:file-list="fileList"
      class="upload-demo"
      action=""
      :http-request="handleUpload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :limit="1"
      :on-exceed="handleExceed"
      drag
      :multiple="false"
      :disabled="uploading"
    >
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">
          只能上传单个文件，文件大小不超过10MB
        </div>
      </template>
    </el-upload>
    
    <!-- 上传成功后的提示和预览 - 增强版 -->
    <el-dialog
      v-model="dialogVisible"
      :title="uploadedFile ? `文件处理结果 - ${uploadedFile.filename}` : '文件处理结果'"
      width="80%">
      <div v-if="uploadedFile" class="file-info-container">
        <!-- 文件状态提示 -->
        <el-alert
          v-if="uploadedFile.isLocal"
          title="此文件处于本地模式"
          description="文件未能上传到服务器，当前使用本地模式展示"
          type="warning"
          :closable="false"
          class="status-alert"
        />
        
        <!-- 文件错误提示 -->
        <el-alert
          v-if="uploadedFile.error"
          :title="uploadedFile.error"
          type="error"
          :closable="false"
          class="error-alert"
        />
        
        <!-- 文件预览区域 -->
        <div class="preview-container">
          <!-- 图片预览 -->
          <div v-if="previewType === 'image' && uploadedFile.fileUrl" class="image-preview">
            <img :src="getFullPreviewUrl()" alt="文件预览" class="preview-image" />
          </div>
          <!-- 文本预览 -->
          <div v-else-if="previewType === 'text' && uploadedFile.fileUrl" class="text-preview">
            <pre>{{ textPreviewContent }}</pre>
          </div>
          <!-- PDF预览 -->
          <div v-else-if="previewType === 'pdf' && uploadedFile.fileUrl" class="pdf-preview">
            <iframe :src="getFullPreviewUrl()" width="100%" height="400px" frameborder="0"></iframe>
          </div>
          <!-- 视频预览 -->
          <div v-else-if="previewType === 'video' && uploadedFile.fileUrl" class="video-preview">
            <video :src="getFullPreviewUrl()" controls width="100%" height="auto"></video>
          </div>
          <!-- 音频预览 -->
          <div v-else-if="previewType === 'audio' && uploadedFile.fileUrl" class="audio-preview">
            <audio :src="getFullPreviewUrl()" controls></audio>
          </div>
          <!-- 不支持预览的文件类型或文件URL不存在 -->
          <div v-else class="no-preview">
            <div class="file-icon-container">
              <div class="file-icon">📄</div>
            </div>
            <div class="file-message">
              <p v-if="!uploadedFile.fileUrl">无法预览此文件</p>
              <p v-else>该文件类型不支持在线预览</p>
            </div>
          </div>
        </div>
        
        <!-- 文件信息 - 增强版 -->
        <div class="file-info">
          <div class="info-grid">
            <div class="info-item">
              <strong>文件名称：</strong>
              <span class="filename">{{ uploadedFile.filename }}</span>
            </div>
            <div class="info-item">
              <strong>文件大小：</strong>
              <span>{{ formatFileSize(fileSize) }}</span>
            </div>
            <div class="info-item">
              <strong>上传时间：</strong>
              <span>{{ formatDate(new Date()) }}</span>
            </div>
            <div class="info-item">
              <strong>状态：</strong>
              <span v-if="uploadedFile.isLocal" class="status-local">本地模式</span>
              <span v-else class="status-server">服务器模式</span>
            </div>
            <div class="info-item" v-if="uploadedFile.type">
              <strong>文件类型：</strong>
              <span>{{ uploadedFile.type || '未知' }}</span>
            </div>
          </div>
          <p class="url-container">
            <strong>文件URL：</strong>
            <el-tooltip effect="top" content="点击复制">
              <span 
                class="file-url" 
                @click="copyFileUrl"
                :class="{ 'url-unavailable': !uploadedFile.fileUrl }"
              >
                {{ uploadedFile.fileUrl || '不可用' }}
              </span>
            </el-tooltip>
          </p>
        </div>
      </div>
      <div v-else class="empty-state">
        <el-empty description="暂无文件信息"></el-empty>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">关闭</el-button>
          <el-button 
            type="primary" 
            @click="downloadFile"
            :disabled="!uploadedFile?.fileUrl"
          >
            下载文件
          </el-button>
          <el-button 
            v-if="uploadedFile?.isLocal"
            type="warning" 
            @click="handleUpload({ file: currentLocalFile })"
            :loading="uploading"
          >
            {{ uploading ? '重新上传中...' : '重新上传' }}
          </el-button>
          <el-button 
            type="success" 
            @click="copyFileUrl"
            :disabled="!uploadedFile?.fileUrl"
          >
            复制URL
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue'
import { ElMessage, ElEmpty } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import { uploadFile, downloadFile as downloadFileService } from '../services/fileService'
import localFileService from '../services/localFileService'

export default {
  name: 'FileUploader',
  components: {
    UploadFilled,
    ElEmpty
  },
  props: {
    maxSize: {
      type: Number,
      default: 10 * 1024 * 1024 // 10MB
    },
    accept: {
      type: String,
      default: '*' // 接受所有类型的文件
    }
  },
  emits: ['file-uploaded'],
  setup(props, { emit }) {
    // 响应式状态
    const fileList = ref([])
    const dialogVisible = ref(false)
    const uploadedFile = ref(null)
    const fileSize = ref(0)
    const textPreviewContent = ref('')
    const uploading = ref(false) // 上传状态
    const downloading = ref(false) // 下载状态
    const currentLocalFile = ref(null) // 当前本地文件引用
    

    
    // 创建下载链接并触发点击
    const createDownloadLink = (url, filename) => {
      const link = document.createElement('a')
      link.href = url
      link.download = filename || 'downloaded_file'
      link.style.display = 'none'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }
    

    
    // 计算文件类型和预览类型
    const fileType = computed(() => {
      if (!uploadedFile.value || !uploadedFile.value.filename) return ''
      const ext = uploadedFile.value.filename.split('.').pop().toLowerCase()
      return ext
    })
    
    // 判断预览类型
    const previewType = computed(() => {
      const ext = fileType.value
      // 图片类型
      if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'].includes(ext)) {
        return 'image'
      }
      // 文本类型
      if (['txt', 'log', 'md', 'json', 'xml', 'csv', 'html', 'css', 'js', 'ts', 'vue'].includes(ext)) {
        return 'text'
      }
      // PDF类型
      if (ext === 'pdf') {
        return 'pdf'
      }
      // 视频类型
      if (['mp4', 'webm', 'ogg'].includes(ext)) {
        return 'video'
      }
      // 音频类型
      if (['mp3', 'wav', 'ogg'].includes(ext)) {
        return 'audio'
      }
      return null
    })
    
    // 监听上传的文件变化，加载文本预览
    watch(uploadedFile, async (newFile) => {
      if (newFile && previewType.value === 'text') {
        await loadTextPreview()
      }
    })
    
    // 获取完整的预览URL
    const getFullPreviewUrl = () => {
      if (!uploadedFile.value || !uploadedFile.value.fileUrl) return ''
      
      let fileUrl = uploadedFile.value.fileUrl
      console.log('获取预览URL:', fileUrl)
      
      // 完全重建URL处理逻辑
      // 1. 处理blob URL情况
      if (fileUrl.includes('blob:')) {
        // 提取正确的blob URL格式
        const match = fileUrl.match(/blob:[^\s]*/)
        if (match) {
          fileUrl = match[0]
          console.log('提取到的blob URL:', fileUrl)
          return fileUrl
        } else {
          // 如果无法正确提取blob URL，使用本地URL策略
          console.warn('无法提取有效的blob URL，切换到本地处理')
        }
      }
      
      // 2. 处理普通URL情况
      // 检查是否已经是完整URL
      if (fileUrl.startsWith('http://') || fileUrl.startsWith('https://')) {
        console.log('使用完整URL直接返回')
        return fileUrl
      }
      
      // 3. 构建完整URL
      const baseUrl = window.location.origin
      
      // 确保路径格式正确
      if (fileUrl.startsWith('/')) {
        // 已经是绝对路径
        return `${baseUrl}${fileUrl}`
      } else {
        // 智能处理相对路径
        // 检查是否已经包含API相关路径
        if (fileUrl.includes('/api/') || fileUrl.includes('api/')) {
          return `${baseUrl}/${fileUrl}`
        } else if (fileUrl.includes('/file/') || fileUrl.includes('file/')) {
          // 如果已经包含file路径，可能只需要添加/api前缀
          if (fileUrl.startsWith('file/')) {
            return `${baseUrl}/api/${fileUrl}`
          }
          return `${baseUrl}${fileUrl}`
        } else {
          // 默认情况，尝试多种可能的路径格式
          // 1. 直接作为文件名访问
          // 2. 通过标准的文件访问API路径
          // 优先使用第二种方式
          return `${baseUrl}/api/file/${fileUrl}`
        }
      }
    }
    
    // 加载文本文件预览
    const loadTextPreview = async () => {
      try {
        textPreviewContent.value = '正在加载文件内容...'
        
        // 对于本地文件，优先使用本地文件服务读取
        if (currentLocalFile.value && currentLocalFile.value.raw) {
          console.log('使用本地文件服务读取文件内容')
          try {
            const content = await localFileService.readTextContent(currentLocalFile.value.raw)
            textPreviewContent.value = content || '文件内容为空'
          } catch (localError) {
            console.error('本地读取文本失败:', localError)
            textPreviewContent.value = '本地读取文件内容失败'
          }
          return
        }
        
        // 如果是本地预览模式，但没有原始文件引用
        if (uploadedFile.value?.isLocal) {
          textPreviewContent.value = '本地预览模式下无法加载文本内容，请尝试重新上传'
          return
        }
        
        // 如果是服务器上的文件，则尝试从服务器获取
        console.log('尝试从服务器获取文件内容')
        const fullUrl = uploadedFile.value.fileUrl
        
        // 添加超时控制
        const controller = new AbortController()
        const timeoutId = setTimeout(() => controller.abort(), 10000)
        
        const response = await fetch(fullUrl, {
          signal: controller.signal
        })
        
        clearTimeout(timeoutId)
        
        if (response.ok) {
          textPreviewContent.value = await response.text()
        } else {
          textPreviewContent.value = `无法加载文件内容 (${response.status})`
        }
      } catch (error) {
        console.error('加载文本预览失败:', error)
        if (error.name === 'AbortError') {
          textPreviewContent.value = '加载超时，请稍后重试'
        } else {
          textPreviewContent.value = `无法加载文件内容: ${error.message || '未知错误'}`
        }
      }
    }
    
    // 文件上传前的校验
    const beforeUpload = (rawFile) => {
      // 检查文件大小
      if (rawFile.size > props.maxSize) {
        ElMessage.error(`文件大小不能超过${(props.maxSize / 1024 / 1024).toFixed(1)}MB`)
        return false
      }
      
      // 保存文件大小
      fileSize.value = rawFile.size
      
      return true
    }
    
    // 处理文件上传 - 增强版，确保即使服务器失败也能提供良好的用户体验
    const handleUpload = async ({ file }) => {
      try {
        uploading.value = true
        currentLocalFile.value = file // 保存本地文件引用
        
        // 显示上传中提示
        ElMessage({ message: '正在处理文件...', type: 'loading', duration: 0 })
        
        console.log('=== 开始处理文件 ===', { name: file.name, type: file.type, size: file.size })
        
        // 获取文件的基本信息，无论上传是否成功都需要
        const fileInfo = {
          filename: file.name,
          size: file.size,
          type: file.raw?.type || 'application/octet-stream',
          isLocal: true,
          previewType: localFileService.getPreviewType(file.raw || file)
        }
        
        let finalFile = null
        
        try {
          console.log('尝试上传到服务器...')
          // 调用上传服务，确保传递有效的文件对象
          const result = await uploadFile(file.raw || file)
          
          console.log('服务器上传成功，返回结果:', result)
          
          // 合并服务器返回结果和基本文件信息
          finalFile = {
            ...result,
            ...fileInfo,
            isLocal: false, // 服务器上传成功，不是本地文件
            size: file.size // 确保size是正确的
          }
          
          ElMessage.success(`文件上传成功：${result.filename}`)
        } catch (uploadError) {
          console.error('=== 服务器上传失败，切换到本地模式 ===', uploadError.message || uploadError)
          
          // 无论文件是否可预览，都为用户提供基本的文件信息展示
          try {
            console.log('创建本地文件信息...')
            
            // 尝试为所有文件创建基本的本地引用，即使不能预览
            let localUrl = null
            if (localFileService.isPreviewable(file.raw || file)) {
              // 对于可预览的文件，创建预览URL
              localUrl = await localFileService.createPreviewUrl(file.raw || file)
              fileInfo.previewType = localFileService.getPreviewType(file.raw || file)
              ElMessage.warning('文件未能上传到服务器，但可以在本地预览')
            } else {
              // 对于不可预览的文件，仍然创建文件对象，但不提供预览URL
              ElMessage.warning('服务器暂时不可用，已创建本地文件记录')
            }
            
            finalFile = {
              ...fileInfo,
              fileUrl: localUrl,
              canDownload: true // 标记为可以下载（通过浏览器的Save功能）
            }
          } catch (localError) {
            console.error('创建本地文件信息失败:', localError)
            // 即使创建本地文件信息失败，仍然提供基本的文件记录
            finalFile = {
              ...fileInfo,
              fileUrl: null,
              error: '无法创建本地预览，但已记录文件信息'
            }
            ElMessage.warning('服务器暂时不可用，已记录文件基本信息')
          }
        }
        
        // 保存最终的文件信息并显示对话框
        uploadedFile.value = finalFile
        dialogVisible.value = true
        
        // 触发文件处理完成事件，包含所有必要的文件信息
        emit('file-uploaded', finalFile)
      } catch (error) {
        console.error('处理文件上传过程中的错误:', error)
        
        // 显示详细错误信息
        let errorMsg = error.message || '文件上传失败'
        ElMessage.error(errorMsg)
      } finally {
        uploading.value = false
        // 关闭加载提示
        ElMessage.closeAll()
      }
    }
    
    // 处理文件预览
    const handlePreview = async (file) => {
      try {
        // 保存当前文件引用
        currentLocalFile.value = file
        
        // 对于图片、视频、音频等，使用本地预览
        if (file.url) {
          // 如果是文本文件，先读取内容
          if (previewType.value === 'text' && file.raw) {
            const reader = new FileReader()
            reader.onload = (e) => {
              textPreviewContent.value = e.target.result || ''
              showPreviewDialog(file)
            }
            reader.readAsText(file.raw)
          } else {
            showPreviewDialog(file)
          }
        }
      } catch (error) {
        console.error('预览错误:', error)
        ElMessage.error('文件预览失败')
      }
    }
    
    // 显示预览对话框
    const showPreviewDialog = (file) => {
      // 创建临时的上传文件对象用于预览
      uploadedFile.value = {
        filename: file.name,
        fileUrl: file.url || '',
        size: file.size
      }
      dialogVisible.value = true
    }
    
    // 处理文件移除
    const handleRemove = () => {
      // 清空文件列表
      fileList.value = []
      
      // 清理blob URL以避免内存泄漏
      if (uploadedFile.value?.fileUrl) {
        localFileService.cleanupObjectUrl(uploadedFile.value.fileUrl)
      }
      
      // 清空上传文件信息
      uploadedFile.value = null
      // 清空文本预览内容
      textPreviewContent.value = ''
      // 清空当前本地文件引用
      currentLocalFile.value = null
      // 关闭预览对话框
      dialogVisible.value = false
      ElMessage.info('文件已从列表移除')
    }
    
    // 处理文件超出限制
    const handleExceed = () => {
      ElMessage.warning('当前限制最多上传1个文件')
    }
    
    // 复制文件URL到剪贴板
    const copyFileUrl = async () => {
      try {
        if (uploadedFile.value && uploadedFile.value.fileUrl) {
          // 使用已经处理过URL的getFullPreviewUrl函数
          const fullUrl = getFullPreviewUrl()
          await navigator.clipboard.writeText(fullUrl)
          ElMessage.success('文件URL已复制到剪贴板')
        }
      } catch (error) {
        console.error('复制失败:', error)
        ElMessage.error('复制失败，请手动复制')
      }
    }
    
    // 下载文件 - 增强版，支持本地文件和服务器文件，更健壮的错误处理
    const downloadFile = async () => {
      if (!uploadedFile.value || (!uploadedFile.value.fileUrl && !uploadedFile.value.canDownload)) {
        ElMessage.warning('无法下载此文件')
        return
      }
      
      try {
        downloading.value = true
        
        let { filename, fileUrl, isLocal } = uploadedFile.value
        
        // 更精确地提取blob URL
        if (fileUrl && fileUrl.includes('blob:')) {
          const match = fileUrl.match(/blob:[^\s]*/)
          if (match) {
            fileUrl = match[0]
            console.log('提取到的blob URL:', fileUrl)
          }
        }
        
        console.log('准备下载文件:', filename, 'URL:', fileUrl)
        
        // 对于blob URL或本地文件，优先使用本地文件服务下载
        if (fileUrl && fileUrl.startsWith('blob:') || isLocal) {
          console.log('使用本地文件服务下载')
          
          // 优先尝试使用原始文件对象创建下载
          if (currentLocalFile.value?.raw) {
            try {
              const url = URL.createObjectURL(currentLocalFile.value.raw)
              createDownloadLink(url, uploadedFile.value.filename)
              // 清理URL对象
              setTimeout(() => URL.revokeObjectURL(url), 100)
              ElMessage.success(`开始下载文件: ${filename}`)
            } catch (localError) {
              console.warn('使用原始文件下载失败，尝试其他方式:', localError)
              // 尝试使用fileUrl下载
              if (uploadedFile.value.fileUrl) {
                createDownloadLink(uploadedFile.value.fileUrl, uploadedFile.value.filename)
                ElMessage.success(`开始下载文件: ${filename}`)
              } else {
                throw new Error('无法创建下载链接')
              }
            }
          } else if (fileUrl) {
            // 使用已有的fileUrl下载
            createDownloadLink(fileUrl, filename)
            ElMessage.success(`开始下载文件: ${filename}`)
            
            // 清理blob URL以避免内存泄漏
            setTimeout(() => {
              localFileService.cleanupObjectUrl(fileUrl)
            }, 100)
          } else {
            throw new Error('没有可用的下载源')
          }
        } else {
          // 对于服务器文件，尝试服务端下载
          try {
            await downloadFileService(filename, fileUrl)
            ElMessage.success(`开始下载文件: ${filename}`)
          } catch (serverError) {
            console.error('服务器下载失败，尝试备用方式:', serverError)
            
            // 如果服务端下载失败，尝试使用简单的链接方式
            try {
              console.log('尝试使用备用下载方式')
              const fullUrl = getFullPreviewUrl()
              window.open(fullUrl, '_blank')
              ElMessage.warning('已在新标签页打开文件，请尝试手动保存')
            } catch (fallbackError) {
              console.error('备用下载方式也失败:', fallbackError)
              throw new Error('所有下载方式均失败')
            }
          }
        }
      } catch (error) {
        console.error('下载错误详情:', error)
        
        // 提供详细的错误信息
        let errorMsg = '文件下载失败'
        if (error.message) {
          errorMsg = `下载失败: ${error.message}`
        }
        ElMessage.error(errorMsg)
      } finally {
        downloading.value = false
      }
    }
    
    // 格式化文件大小
    const formatFileSize = (bytes) => {
      if (!bytes || bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }
    
    // 格式化日期
    const formatDate = (date) => {
      return new Date(date).toLocaleString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
      })
    }
    
    return {
      fileList,
      dialogVisible,
      uploadedFile,
      fileSize,
      textPreviewContent,
      previewType,
      uploading,
      beforeUpload,
      handleUpload,
      handlePreview,
      handleRemove,
      handleExceed,
      copyFileUrl,
      downloadFile,
      formatFileSize,
      formatDate,
      getFullPreviewUrl
    }
  },
  // 组件卸载前清理
  beforeUnmount() {
    // 清理消息
    ElMessage.closeAll()
    
    // 清理blob URL以避免内存泄漏
    if (this.uploadedFile?.fileUrl) {
      localFileService.cleanupObjectUrl(this.uploadedFile.fileUrl)
    }
  }
}
</script>

<style scoped>
  .upload-container {
    width: 100%;
    padding: 20px;
  }
  
  .upload-dragger {
    width: 100%;
    height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px dashed #dcdfe6;
    border-radius: 8px;
    background-color: #fafafa;
    transition: all 0.3s;
    cursor: pointer;
  }
  
  .upload-dragger:hover {
    border-color: #409eff;
    background-color: #f5f7fa;
  }
  
  .upload-dragger__text {
    text-align: center;
    color: #909399;
  }
  
  .upload-dragger__icon {
    font-size: 48px;
    margin-bottom: 16px;
  }
  
  .file-info-container {
    padding: 20px;
  }
  
  /* 状态提示样式 */
  .status-alert,
  .error-alert {
    margin-bottom: 20px;
  }
  
  /* 预览容器样式 */
  .preview-container {
    margin-bottom: 24px;
    padding: 16px;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    background-color: #fafafa;
    min-height: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  /* 图片预览样式 */
  .image-preview {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .preview-image {
    max-width: 100%;
    max-height: 400px;
    object-fit: contain;
    border-radius: 4px;
  }
  
  /* 文本预览样式 */
  .text-preview {
    width: 100%;
    background-color: #fff;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    max-height: 400px;
    overflow-y: auto;
  }
  
  .text-preview pre {
    margin: 0;
    padding: 16px;
    white-space: pre-wrap;
    word-break: break-all;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
  }
  
  /* 视频预览样式 */
  .video-preview {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  /* 音频预览样式 */
  .audio-preview {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  /* PDF预览样式 */
  .pdf-preview {
    width: 100%;
    height: 400px;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  /* 不支持预览的文件样式 */
  .no-preview {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px;
    color: #909399;
  }
  
  .file-icon-container {
    margin-bottom: 16px;
  }
  
  .file-icon {
    font-size: 48px;
    color: #c0c4cc;
  }
  
  .file-message {
    text-align: center;
  }
  
  /* 文件信息样式 - 增强版 */
  .file-info {
    padding: 16px;
    background-color: #f8f9fa;
    border-radius: 4px;
    margin-bottom: 20px;
  }
  
  .info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
  }
  
  .info-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
  
  .info-item strong {
    color: #606266;
    min-width: 100px;
    font-weight: 500;
  }
  
  .filename {
    color: #303133;
    font-weight: 500;
    word-break: break-all;
    flex: 1;
  }
  
  /* 状态标签样式 */
  .status-local {
    color: #e6a23c;
    padding: 2px 8px;
    background-color: #fdf6ec;
    border-radius: 4px;
    font-size: 12px;
  }
  
  .status-server {
    color: #67c23a;
    padding: 2px 8px;
    background-color: #f0f9ff;
    border-radius: 4px;
    font-size: 12px;
  }
  
  /* URL容器样式 */
  .url-container {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid #e4e7ed;
  }
  
  .file-url {
    color: #409eff;
    cursor: pointer;
    word-break: break-all;
    padding: 4px 8px;
    background-color: #f4f4f5;
    border-radius: 4px;
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: all 0.3s;
  }
  
  .file-url:hover {
    background-color: #ecf5ff;
  }
  
  .file-url.url-unavailable {
    color: #909399;
    cursor: not-allowed;
    background-color: #f4f4f5;
  }
  
  .file-url.url-unavailable:hover {
    background-color: #f4f4f5;
  }
  
  /* 空状态样式 */
  .empty-state {
    padding: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  /* 对话框底部样式 */
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
  }
  
  /* 响应式设计 */
  @media (max-width: 768px) {
    .info-grid {
      grid-template-columns: 1fr;
    }
    
    .preview-container {
      padding: 12px;
    }
    
    .file-info-container {
      padding: 12px;
    }
  }
  </style>